package sh.orm;

import sh.orm.annotation.Entity;
import sh.orm.convert.JdbcType;
import sh.orm.util.ClassUtil;
import sh.orm.util.NameUtil;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

/**
 * @author lqq
 * @date 2019/1/22
 */
public class EntityUtil {



    public static <T> Map<String,Object> getColumnValueMap(T entity) {

        Map<String,Object> columnValueMap = new HashMap<>();
        addField(ClassUtil.getRealEntityClass(entity.getClass()) , entity , columnValueMap);
        return columnValueMap;
    }

    /**
     * 递归把所有的属性都放进去
     * @param entity
     * @param columnValueMap
     * @param <T>
     */
    private static <T> void addField(Class<?> clazz , T entity,Map<String,Object> columnValueMap){

        // 这里只能访问到本类的属性
        for(Field field : clazz.getDeclaredFields()){
            //设置为可以访问，否则private访问不了
            field.setAccessible(true);
            //TRANSIENT: 128 （二进制 1000 0000）
            //这里的 或与非操作，最终判断有transient修饰符跳过
            int modifier = field.getModifiers();
            if((modifier & 128) == 128){
                //如果有transient，跳过
                continue;
            }
            String fieldName = field.getName();
            String columnName = NameUtil.convertHumpToUnderline(fieldName);
            try {
                columnValueMap.put(columnName,field.get(entity));
            } catch (IllegalAccessException e) {
                e.printStackTrace();
                throw new OrmException("获取属性值异常" + e.getMessage());
            }
        }

        if(!"Object".equals(clazz.getSuperclass().getSimpleName())){
            addField(clazz.getSuperclass(),entity,columnValueMap);
        }
    }

    /**
     * 获取到字段对应的数据库类型
     * @param entityClass
     * @param field 字段
     * @return
     */
    public static JdbcType getJdbcType(Class<?> entityClass, String field ) {
        //
        String tableName = StaticEntityHolder.getStaticEntity(ClassUtil.getRealEntityClass(entityClass)).getTableName();
        return DatabaseMetadata.getInstance().getTableMetadataMap().get(tableName).getFieldJdbcTypeMap().get(field);
    }

    /**
     * 判断一个类是否是entity，
     * 通过判断是否有@Entity注解来判断
     * @param aClass
     * @return
     */
    public static boolean isEntity(Class<?> aClass) {
        Class clazz = ClassUtil.getRealEntityClass(aClass);
        if(clazz.isAnnotationPresent(Entity.class)){
            return true;
        }
        return false;
    }

    /**
     * 判断clazz是否需要代理
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> boolean hasRelationAnnotation(Class<T> clazz) {
        if(StaticEntityHolder.getStaticEntity(ClassUtil.getRealEntityClass(clazz)).getFieldRelationAnnotationsMap().size() > 0){
            return true;
        }
        return false;
    }
}
